package com.nbclass.modules.sys.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nbclass.common.constant.CoreConst;
import com.nbclass.common.util.AuthorizationUtils;
import com.nbclass.common.util.CopyUtil;
import com.nbclass.common.util.PageUtil;
import com.nbclass.common.util.PasswordHelper;
import com.nbclass.common.util.StringUtils;
import com.nbclass.common.util.UUIDUtil;
import com.nbclass.common.util.poi.ExcelUtil;
import com.nbclass.common.util.text.Convert;
import com.nbclass.common.vo.AjaxResultVo;
import com.nbclass.config.shiro.ShiroUtils;
import com.nbclass.modules.base.BaseController;
import com.nbclass.modules.sys.model.SysRole;
import com.nbclass.modules.sys.model.SysUser;
import com.nbclass.modules.sys.service.RoleService;
import com.nbclass.modules.sys.service.UserService;
import com.nbclass.modules.sys.vo.ChangePasswordVo;

@Controller
@RequestMapping("/user")
public class UserController extends BaseController {

	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;

	/**
	 * 权限管理--用户管理
	 */
	@GetMapping("/toUserPage")
	public String userList() {
		return "user/list";
	}

	/**
	 * 用户列表数据
	 * 
	 * @param user
	 * @param limit
	 * @param offset
	 * @return
	 */
	@RequiresPermissions("user:list")
	@PostMapping("/list")
	@ResponseBody
	public AjaxResultVo listUsers(SysUser user, Integer limit, Integer offset) {
		try {
			PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
			List<SysUser> userList = userService.listUsers(user);
			PageInfo<SysUser> pageResult = new PageInfo<>(userList);
			AjaxResultVo resultVo = AjaxResultVo.success();
			resultVo.put("rows", pageResult.getList());
			resultVo.put("total", pageResult.getTotal());
			return resultVo;
		} catch (Exception e) {
			logger.error(String.format("用户列表数据查询异常 UserController.listUsers%s", e));
			return AjaxResultVo.error("查询失败");
		}
	}

	/**
	 * 跳转新增用户
	 * 
	 * @return
	 */
	@RequiresPermissions("user:add")
	@GetMapping("/add")
	public String add() {
		return "user/add";
	}

	/**
	 * 新增用户
	 * 
	 * @param userForm
	 * @param confirmPassword
	 * @return
	 */
	@RequiresPermissions("user:add")
	@PostMapping("/doAdd")
	@ResponseBody
	public AjaxResultVo addUser(SysUser userForm, String confirmPassword) {
		try {
			String username = userForm.getUsername();
			SysUser user = userService.getUserByUsername(username);
			if (null != user) {
				return AjaxResultVo.error("用户名已存在");
			}
			String password = userForm.getPassword();
			// 判断两次输入密码是否相等
			if (confirmPassword != null && password != null) {
				if (!confirmPassword.equals(password)) {
					return AjaxResultVo.error("两次密码不一致");
				}
			}
			userForm.setUserId(Long.valueOf(UUIDUtil.getUniqueIdByUUId()));
			userForm.setStatus(CoreConst.STATUS_VALID);
			Date date = new Date();
			userForm.setCreateTime(date);
			userForm.setUpdateTime(date);
			userForm.setLastLoginTime(date);
			PasswordHelper.encryptPassword(userForm);
			int num = userService.register(userForm);
			if (num > 0) {
				return AjaxResultVo.success("添加用户成功");
			} else {
				return AjaxResultVo.error("添加用户失败");
			}
		} catch (Exception e) {
			logger.error(String.format("新增后台用户异常 UserController.addUser%s", e));
			return AjaxResultVo.error("添加用户失败");
		}
	}

	/**
	 * 编辑用户详情
	 * 
	 * @param model
	 * @param userId
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@GetMapping("/edit")
	public String userDetail(Model model, String userId) {
		SysUser user = userService.getUserByUserId(Long.valueOf(userId));
		model.addAttribute("user", user);
		return "user/detail";
	}

	/**
	 * 编辑用户
	 * 
	 * @param sysUser
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResultVo editUser(SysUser sysUser) {
		try {
			int a = userService.updateUserByUserId(sysUser);
			if (a > 0) {
				return AjaxResultVo.success("编辑用户成功！");
			} else {
				return AjaxResultVo.error("编辑用户失败");
			}
		} catch (Exception e) {
			logger.error(String.format("编辑后台用户异常 UserController.editUser%s", e));
			return AjaxResultVo.error("编辑用户失败");
		}
	}

	/**
	 * 变更用户状态
	 * 
	 * @param userId
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@PostMapping("/changeUserStatus")
	@ResponseBody
	public AjaxResultVo changeUserStatus(String userId) {
		try {
			if (StringUtils.isEmpty(userId)) {
				return AjaxResultVo.error("参数错误");
			}
			int result = userService.updateUserStatusByUserId(userId);
			if (result > 0) {
				return AjaxResultVo.success("变更成功");
			} else {
				return AjaxResultVo.error("变更失败");
			}
		} catch (Exception e) {
			logger.error(String.format("变更用户状态异常 UserController.changeUserStatus%s", e));
			return AjaxResultVo.error("变更失败");
		}
	}

	/**
	 * 编辑用户详情
	 * 
	 * @param model
	 * @param userId
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@GetMapping("/assign")
	public String assign(Model model, String userId) {
		model.addAttribute("userId", userId);
		return "user/assign";
	}

	/**
	 * 分配角色列表查询
	 * 
	 * @param userId
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@PostMapping("/assign/role/list")
	@ResponseBody
	public AjaxResultVo listAssignRole(String userId) {
		try {
			List<SysRole> roleList = roleService.listRoles(new SysRole());
			Set<String> hasRoles = roleService.listRoleIdsByUserId(Long.valueOf(userId));
			AjaxResultVo resultVo = AjaxResultVo.success();
			resultVo.put("rows", roleList);
			resultVo.put("hasRoles", hasRoles);
			return resultVo;
		} catch (Exception e) {
			logger.error(String.format("分配角色列表查询异常 UserController.listAssignRole%s", e));
			return AjaxResultVo.error("查询失败");
		}
	}

	/**
	 * 保存分配角色
	 * 
	 * @param userId
	 * @param roleIdStr
	 * @return
	 */
	@RequiresPermissions("user:edit")
	@PostMapping("/assign/role")
	@ResponseBody
	public AjaxResultVo assignRole(String userId, String roleIdStr) {
		try {
			Long[] roleIdsList = Convert.toLongArray(",", roleIdStr);
			AjaxResultVo resultVo = userService.addAssignRole(Long.valueOf(userId), roleIdsList);
			List<Long> userIds = new ArrayList<>();
			userIds.add(Long.valueOf(userId));
			AuthorizationUtils.clearAllCachedAuthorizationInfo();
			return resultVo;
		} catch (Exception e) {
			logger.error(String.format("保存分配角色异常 UserController.assignRole%s", e));
			return AjaxResultVo.error("保存失败");
		}
	}

	/**
	 * 用户中心 -- 用户详情跳转
	 * 
	 * @return
	 */
	@GetMapping("/updateUser")
	public String updateUser() {
		return "ucenter/info";
	}

	/**
	 * 用户中心 -- 修改密码跳转
	 * 
	 * @return
	 */
	@GetMapping("/updatePwd")
	public String updatePwd() {
		return "ucenter/pwd";
	}

	/**
	 * 用户中心 -- 修改密码
	 * 
	 * @param changePasswordVo
	 * @return
	 */
	@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
	@ResponseBody
	public AjaxResultVo changePassword(ChangePasswordVo changePasswordVo) {
		try {
			if (!changePasswordVo.getNewPassword().equals(changePasswordVo.getConfirmNewPassword())) {
				return AjaxResultVo.error("两次密码输入不一致");
			}
			SysUser loginUser = userService.getUserByUserId(ShiroUtils.getUserId());
			// 对象复制
			SysUser newUser = CopyUtil.getCopy(loginUser, SysUser.class);
			// 重新赋值
			String sysOldPassword = loginUser.getPassword();
			newUser.setPassword(changePasswordVo.getOldPassword());
			String entryOldPassword = PasswordHelper.getPassword(newUser);
			if (sysOldPassword.equals(entryOldPassword)) {
				newUser.setPassword(changePasswordVo.getNewPassword());
				PasswordHelper.encryptPassword(newUser);
				userService.updateUserByUserId(newUser);
				AuthorizationUtils.clearAllCachedAuthorizationInfo();
			} else {
				return AjaxResultVo.error("您输入的旧密码有误");
			}
			return AjaxResultVo.success("修改密码成功");
		} catch (Exception e) {
			logger.error(String.format("用户中心 -- 修改密码异常 UserController.changePassword%s", e));
			return AjaxResultVo.error("修改密码失败");
		}
	}

	/**
	 * 导出用户
	 * 
	 * @param user
	 * @return
	 */
	@PostMapping("/export")
	@ResponseBody
	public AjaxResultVo exportUser(SysUser user) {
		try {
			List<SysUser> list = userService.listUsers(user);
			ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
			return util.exportExcel(list, "用户数据");
		} catch (Exception e) {
			logger.error(String.format("导出用户异常 UserController.exportUser%s", e));
			return AjaxResultVo.error("导出失败");
		}
	}

	/**
	 * 导入用户
	 * 
	 * @param file
	 * @param updateSupport
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/importData")
	@ResponseBody
	public AjaxResultVo importUser(MultipartFile file, boolean updateSupport) {
		try {
			ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
			List<SysUser> userList = util.importExcel(file.getInputStream());
			String operName = ShiroUtils.getUser().getUsername();
			String message = userService.importUser(userList, updateSupport, operName);
			return AjaxResultVo.success(message);
		} catch (Exception e) {
			logger.error(String.format("导入用户异常 UserController.importUser%s", e));
			return AjaxResultVo.error("导入失败");
		}
	}

	/**
	 * 下载导入模板
	 * 
	 * @return
	 */
	@GetMapping("/importTemplate")
	@ResponseBody
	public AjaxResultVo importTemplate() {
		try {
			ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
			return util.importTemplateExcel("用户数据");
		} catch (Exception e) {
			logger.error(String.format("下载导入模板异常 UserController.importTemplate%s", e));
			return AjaxResultVo.error("下载失败");
		}
	}

}
